#!/usr/local/bin/perl -w

use App::Options (
    options => [qw(dbhost dbname dbuser dbpass)],
);

use lib "lib";
use lib "../lib";
use lib ".";
use lib "t";

use strict;

use Test::More qw(no_plan);
use App;
use App::WorkQueue::Memory;

#foreach my $key (sort keys %INC) {
#    printf("%-28s : %s\n", $key, $INC{$key});
#}

my $context = App->context();
{
    my ($errmsg);
    my $qname = "test1";
    my $q = $context->work_queue($qname,
        class => "App::WorkQueue::Memory",
        id_attrib => "pi",
        status_attrib => "status",
        STATUS_UNACQUIRED => "A",
        STATUS_BUFFERED => "B",
        STATUS_ACQUIRED => "C",
        STATUS_RELEASED => "D",
    );
    isa_ok($q, "App::WorkQueue");
    isa_ok($q, "App::WorkQueue::Memory");

    eval {
        $q->push({ pi => 3.1416, status => "X", });
    };
    ok(!$@, "Error on $qname->push(hash) [$@]");

    eval {
        $q->push([ 1, 3.1416, "X" ]);
    };
    $errmsg = $@;
    $errmsg =~ s/ at .*//s if ($errmsg);
    ok($errmsg, "Error on $qname->push(array) [$errmsg]");
}

{
    my ($errmsg, %colidx);
    my $columns = [qw(
        shop_request_id
        org_id prop_id shop_data_source
        shop_currency_cd shop_pos_cd los guests
        begin_arv_dt end_arv_dt dow comp_id comp_prod_id
        scheduled_dttm start_dttm complete_dttm change_dttm
        request_status client_userid client_system_cd server_system_cd
        work_units work_units_complete
        request_msg email_notify email_type shop_units profile
        work_units_error work_units_blank shop_host shop_priority shop_fresh_mins
        actual_data_source file_output_ind work_units_skipped override_data_source
        display_option prev_day_compare mkt_keyword shop_level
    )];
    for (my $i = 0; $i <= $#$columns; $i++) {
        $colidx{$columns->[$i]} = $i;
    }

    my $qname = "hotel_shop_subrequest";
    my $q = $context->work_queue($qname,
        class             => "App::WorkQueue::Memory",
        id_attrib         => "shop_request_id,comp_id,begin_arv_dt,shop_data_source,los",
        status_attrib     => "request_status",
        STATUS_UNACQUIRED => "N",
        STATUS_BUFFERED   => "B",
        STATUS_ACQUIRED   => "R",
        STATUS_RELEASED   => "S",
        columns           => $columns,
        sort_spec         => "N-shop_priority,scheduled_dttm,N+shop_request_id,begin_arv_dt,comp_id",
    );
    isa_ok($q, "App::WorkQueue");
    isa_ok($q, "App::WorkQueue::Memory");

    eval {
        $q->push({ pi => 3.1416 });
    };
    $errmsg = $@;
    $errmsg =~ s/ at .*//s if ($errmsg);
    ok($errmsg, "Error on $qname->push(hash) [$errmsg]");

    eval {
        $q->push([ 1,1,128,"TRV","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7","128,129,130","1",
            "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
            "N", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
            0, 0, undef, 2, 1800, undef, undef, 0, undef, "compare.detail.html", "None", undef, 2, ]);
    };
    ok(!$@, "No error on $qname->push(array) [$@]");

    $q->push([ 4,1,128,"EXP","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7","128,129,130","1",
        "2006-01-04 13:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
        "N", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
        0, 0, undef, 2, 1800, undef, undef, 0, undef, "compare.detail.html", "None", undef, 2, ]);
    $q->push([ 2,1,128,"TRV","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7","128,129,130","1",
        "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
        "N", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
        0, 0, undef, 2, 1800, undef, undef, 0, undef, "compare.detail.html", "None", undef, 2, ]);
    $q->push([ 3,1,128,"EXP","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7","128,129,130","1",
        "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
        "N", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
        0, 0, undef, 2, 1800, undef, undef, 0, undef, "compare.detail.html", "None", undef, 2, ]);
    my (%counts);
    $q->count_entries_by_attrib("shop_data_source",\%counts);
    is($counts{TRV}, 2, "TRV count");
    is($counts{EXP}, 2, "EXP count");
    %counts = ();
    $q->count_entries_by_attrib("shop_data_source",\%counts,"work_units");
    is($counts{TRV}, 180, "TRV work_unit count");
    is($counts{EXP}, 180, "EXP work_unit count");

    my (%num_workers_ds, %num_workers_ads);
    my %state = (
        num_workers => 0,
        max_workers => -2,
    );
    my %max_workers_ds = (
        TRV => -1,
        WEB => -2,
        GDS => -2,
        _DEFAULT => -2,
    );
    my %max_workers_ads = (
        GDS_VHH => 1,
        GDS_VMC => 1,
        GDS_VSI => 1,
        GDS_VIC => 1,
        GDS_VHY => 1,
        VHH => -1,
        VMC => 1,
        VSI => 1,
        VIC => 1,
        VHY => 1,
    );
    eval {
        $q->set_constraint(\%num_workers_ds,  \%max_workers_ds,  "shop_data_source");
        ok(1, "set_constraint(shop_data_source)");
        $q->set_constraint(\%num_workers_ads, \%max_workers_ads, "actual_data_source");
        ok(1, "set_constraint(actual_data_source)");
        $q->set_global_constraint(\%state, \%state, "num_workers", "max_workers");
        ok(1, "set_global_constraint(...)");
    };
    ok(!$@, "No errors [$@]");

    my ($e1, $e2, $e3, $e4);

    $e1 = $q->acquire();
    is($e1->[0], 1,     "Entry 1: id=1");
    is($e1->[3], "TRV", "Entry 1: shop_data_source=TRV");
    is($num_workers_ds{TRV},  1,     "Entry 1: num_workers_ds{TRV} = 1");
    is($num_workers_ads{TRV}, undef, "Entry 1: num_workers_ads{TRV} = undef");
    is($state{num_workers},   1,     "Entry 1: state{num_workers} = 1");

    $max_workers_ds{EXP} = 0;
    $e3 = $q->acquire();
    is($e3, undef, "No entries to acquire (EXP constraint)");
    delete $max_workers_ds{EXP};

    $e2 = $q->acquire();
    is($e2->[0], 3,     "Entry 3: id=3");
    is($e2->[3], "EXP", "Entry 3: shop_data_source=EXP");
    is($num_workers_ds{EXP},  1,     "Entry 3: num_workers_ds{EXP} = 1");
    is($num_workers_ads{EXP}, undef, "Entry 3: num_workers_ads{EXP} = undef");
    is($state{num_workers},   2,     "Entry 3: state{num_workers} = 2");

    $q->release($e1);
    is($num_workers_ds{TRV},  0,     "Release 1: num_workers_ds{TRV} = 0");
    is($e1->[$colidx{request_status}], "S", "Entry 1 released: request_status = S");
    is($state{num_workers},   1,     "Release 1: state{num_workers} = 1");

    $e1 = $q->acquire();
    is($e1->[0], 2,     "Entry 2: id=2");
    is($e1->[3], "TRV", "Entry 2: shop_data_source=TRV");
    is($num_workers_ds{TRV},  1,     "Entry 2: num_workers_ds{TRV} = 1");
    is($num_workers_ads{TRV}, undef, "Entry 2: num_workers_ads{TRV} = undef");
    is($state{num_workers},   2,     "Entry 2: state{num_workers} = 2");

    $e3 = $q->acquire();
    is($e3, undef, "No entries to acquire (global constraint)");

    my ($num);
    $num = $q->num_entries();
    is($num, 3, "3 entries left");
    $num = $q->num_entries("R");
    is($num, 2, "2 entries left [R]");
    $num = $q->num_entries("N");
    is($num, 1, "1 entries left [N]");

    is($num_workers_ds{EXP},  1,     "Entry 3: num_workers_ds{EXP} = 1 (still)");
    $q->unacquire($e2);
    is($num_workers_ds{EXP},  0,     "Entry 3 unacquired: num_workers_ds{EXP} = 0");
    is($e2->[$colidx{request_status}], "N", "Entry 3 unacquired: request_status = N");

    $q->push([ 5,1,128,"WEB","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7","128,129,130","1",
        "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
        "N", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
        0, 0, undef, 4, 1800, undef, undef, 0, undef, "compare.detail.html", "None", undef, 2, ]);
    is($q->{data}[0][0], 5, "Entry 5 sorted to top: high priority");
}

exit 0;

